package com.hh.base.util;

import android.content.Context;
import android.content.SharedPreferences;

import com.hh.base.MyUtils;
import com.hh.base.log.SLog;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public final class SPUtils {
    private static final String TAG = "SPUtils";
    private static final Map<String,Editor> sEditorMap = new HashMap<>();
    private static final String SPF_ACCOUNT = "SPUtils_account_";
    private static final String SPF_COMMON = "SPUtils_common";
    private static IUidProvider sUidProvider;

    public interface IUidProvider {
        String getCurrUid();
    }

    public static void setUidProvider(IUidProvider provider) {
        SPUtils.sUidProvider = provider;
    }

    public static Editor common(){
        return get(SPF_COMMON);
    }

    public static Editor account(){
        if(sUidProvider == null){
            throw new NullPointerException("sUidProvider is null,set it first");
        }
        return account(sUidProvider.getCurrUid());
    }

    public static SPUtils.Editor account(String uid){
        return get(SPF_ACCOUNT + uid);
    }

    public static Editor get(String spfName){
        Editor editor = sEditorMap.get(spfName);
        if(editor == null){
            SharedPreferences spf = MyUtils.mContext.getSharedPreferences(spfName, Context.MODE_PRIVATE);
            editor = new Editor(spf);
            sEditorMap.put(spfName,editor);
        }
        return editor;
    }

    public static class Editor{
        private final SharedPreferences mSharedPref;

        public Editor(SharedPreferences sharedPref) {
            this.mSharedPref = sharedPref;
        }

        protected String wrapKey(String key){
            return key;
        }

        public void putStringSet(String key, Set<String> set){
            SharedPreferences.Editor editor = mSharedPref.edit();
            editor.putStringSet(wrapKey(key),set);
            editor.apply();
        }

        public Set<String> getStringSet(String key,Set<String> defValue){
            return mSharedPref.getStringSet(wrapKey(key),defValue);
        }

        public void put(String key, Object value){
            SharedPreferences.Editor editor = mSharedPref.edit();
            key = wrapKey(key);
            if(value == null){
                editor.putString(key,"");
            }else{
                if(value instanceof Integer){
                    editor.putInt(key, (int) value);
                }else if(value instanceof Long){
                    editor.putLong(key,(long)value);
                }else if(value instanceof Float){
                    editor.putFloat(key,(float)value);
                }else if(value instanceof Double){
                    editor.putFloat(key,(float)value);
                }else if(value instanceof Boolean){
                    editor.putBoolean(key,(boolean)value);
                }else{
                    editor.putString(key,String.valueOf(value));
                }
            }
            editor.apply();
        }

        @SuppressWarnings("unchecked")
        public <T> T get(String key, T defaultValue){
            key = wrapKey(key);
            SharedPreferences sp = mSharedPref;
            Object defValue = defaultValue;
            Object result;
            if(defValue == null){
                result = sp.getString(key,null);
            }else{
                if(defValue instanceof Integer){
                    result = sp.getInt(key, (int) defValue);
                }else if(defValue instanceof Long){
                    result = sp.getLong(key, (long) defValue);
                }else if(defValue instanceof Float){
                    result = sp.getFloat(key, (float) defValue);
                }else if(defValue instanceof Double){
                    result = sp.getFloat(key, (float) defValue);
                }else if(defValue instanceof Boolean){
                    result = sp.getBoolean(key, (boolean) defValue);
                }else{
                    result = sp.getString(key,defValue.toString());
                }
            }
            try{
                return (T) result;
            }catch (Exception e){
                e.printStackTrace();
                SLog.w(TAG,String.format("Editor get() Exception,key = %s,default = %s,result = %s",key,defaultValue,result),e);
            }
            return defaultValue;
        }

        public boolean contains(String key){
            return mSharedPref.contains(wrapKey(key));
        }

        public void removeKey(String key){
            mSharedPref.edit().remove(wrapKey(key)).apply();
        }

        public void clear(){
            mSharedPref.edit().clear().apply();
        }
    }

}
